package com.unidt.www.module.bpm.service.task.impl;

import cn.hutool.core.date.DateUtil;
import com.unidt.www.framework.common.util.object.ConvertUtil;
import com.unidt.www.framework.datapermission.core.annotation.DataPermission;
import com.unidt.www.module.bpm.controller.admin.task.vo.task.*;
import com.unidt.www.module.bpm.dal.mysql.definition.ActRuActTimeMapper;
import com.unidt.www.module.bpm.dal.mysql.task.BpmStatisticsMapper;
import com.unidt.www.module.bpm.service.task.BpmStatisticsService;
import com.unidt.www.module.bpm.vo.HourDurationVo;
import com.unidt.www.module.bpm.vo.ProcessCategoryVo;
import com.unidt.www.module.bpm.vo.TaskStatisticsVo;
import com.unidt.www.module.bpm.vo.TaskTimeSlotVo;
import com.unidt.www.module.system.dal.dataobject.user.AdminUserDO;
import com.unidt.www.module.system.dal.mysql.system.SystemDateMapper;
import com.unidt.www.module.system.dal.mysql.user.AdminUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.unidt.www.framework.web.core.util.WebFrameworkUtils.getLoginUserId;

/**
 * @Author sk
 * @Description:
 * @Date 2022/12/1 17:13
 **/
@Service
public class BpmStatisticsServiceImpl implements BpmStatisticsService {
    @Autowired
    BpmStatisticsMapper bpmStatisticsMapper;

    @Autowired
    AdminUserMapper userMapper;

    @Autowired
    SystemDateMapper systemDateMapper;

    @Autowired
    ActRuActTimeMapper actRuActTimeMapper;

    @Override
    @DataPermission(enable = false)
    public HourDurationDateVo getHourDurationDateLine() {

        /**
         * 默认取前15天 包含当天
         */
        String assignee = String.valueOf(getLoginUserId());
        Date startTime = DateUtil.offsetDay(new Date(), -16);
        Date endTime = DateUtil.beginOfDay(new Date());

        List<HourDurationVo> hourDurationVos =
                bpmStatisticsMapper.getHourDurationAvg(assignee, startTime, endTime);


        AdminUserDO userDO = userMapper.selectById(getLoginUserId());

        Long deptId =   userDO.getDeptId();

        List<HourDurationVo> deptHourDurationVos =
                bpmStatisticsMapper.getDeptHourDurationAvg(deptId, startTime, endTime);

        /**
         * xData x轴数据 时间（ 月/日 格式）
         * myDuration 我的任务平均处理时长（小时）
         * deptDuration 我所部门处理任务时长
         * durationAvg 时间范围内 平均处理任务时长
         */
        List<String> xData = systemDateMapper.getList(startTime,endTime);

        List<Double> myDuration = hourDurationVos.stream().map(HourDurationVo::getHourDuration).collect(Collectors.toList());

        List<Double> deptDuration = deptHourDurationVos.stream().map(HourDurationVo::getHourDuration).collect(Collectors.toList());
        Double  durationAvg  =  hourDurationVos.stream().mapToDouble(HourDurationVo::getHourDuration).average().getAsDouble();

        return new   HourDurationDateVo(durationAvg,xData,myDuration,deptDuration);

    }


    @Override
    public List<ProcessCategoryVo> getProcessModelDue() {
        String assignee = String.valueOf(getLoginUserId());
        List<ProcessCategoryVo> list = this.bpmStatisticsMapper.getProcessModelDue(assignee, null, null);

        Integer size = list.size();
        /**
         * 取前三名
         * 超过前三名 归为其他
         */
        if (size <= 4) {
            return list;
        } else {
            List<ProcessCategoryVo> processModelVos = new ArrayList<>();
            processModelVos.add(list.get(0));
            processModelVos.add(list.get(1));
            processModelVos.add(list.get(2));
            processModelVos.add(list.get(3));

            Integer count = 0;

            for (int i = 4; i < size; i++) {
                count = count + list.get(i).getCount();
            }
            ProcessCategoryVo processModelVo = new ProcessCategoryVo();
            processModelVo.setCategoryName("其他");
            processModelVo.setCount(count);
            return processModelVos;
        }

    }

    @Override
    public MyTaskVo getMyTask() {
        Long loginUserId = getLoginUserId();
        Date startTime   = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -16));
        Date endTime     = DateUtil.beginOfDay(new Date());
        MyTaskVo t       =   bpmStatisticsMapper.getUnDoCount(loginUserId, startTime, endTime);
        Integer  timeOutCount = bpmStatisticsMapper.getOutTimeCount(loginUserId,startTime,endTime);
        t.setTimeOutCount(timeOutCount);
        return  t;
    }

    @Override
    public DeptTaskInfoVo getDeptTaskInfo() {

        AdminUserDO userDO = userMapper.selectById(getLoginUserId());
        Long deptId =   userDO.getDeptId();
        Date startTime = DateUtil.offsetDay(new Date(), -16);
        Date endTime =   DateUtil.beginOfDay(new Date());

        List<String> xData = systemDateMapper.getList(startTime,endTime);

        /**
         * 部门任务总数
         * 按照节点startTime统计
         */
        List<TaskStatisticsVo> deptTaskTotalList =
                this.bpmStatisticsMapper.getDeptTaskTotalLine(deptId, startTime, endTime);

        List<Integer> totalList =   deptTaskTotalList.stream().map(TaskStatisticsVo::getTotalCount).collect(Collectors.toList());

        /**
         * 部门任务办结数量
         * 按照节点endTime统计
         */
        List<TaskStatisticsVo> deptTaskEndList = this.bpmStatisticsMapper.getDeptTaskEndLine(deptId, startTime, endTime);
        List<Integer> endList =   deptTaskEndList.stream().map(TaskStatisticsVo::getTotalCount).collect(Collectors.toList());

        return new DeptTaskInfoVo(xData,totalList,endList);
    }

    @Override
    public TaskDayLineVo getUserTaskLine() {

        AdminUserDO userDO = userMapper.selectById(getLoginUserId());


        Long assignee = getLoginUserId();
        Long deptId    =   userDO.getDeptId();
        Date startTime = DateUtil.offsetDay(new Date(), -8);
        Date endTime   = DateUtil.beginOfDay(new Date());
        /**
         * 我的任务完成数量日统计
         * 前7日任务完成数走势
         */
        List<TaskStatisticsVo> endTaskList = this.bpmStatisticsMapper.getMyTaskLine(assignee, startTime, endTime);

        Map<String,List<TaskStatisticsVo>> map =  endTaskList.stream().collect(Collectors.groupingBy(TaskStatisticsVo::getTaskDay));

        List<String> xData =   systemDateMapper.getList(startTime,endTime);

        List<List<Integer>> lists = new ArrayList<>();

        Integer[] timeSlotList =new Integer[]{
                0,4,8,12,16,20
        };
        /**
         * 对应天数的数据
         */
        xData.forEach(x->{

            /**
             * 获取当日任务处理记录
             */
            List<TaskStatisticsVo> list = map.get(x);

            /**
             * 整理时间段
             */
            List<TaskTimeSlotVo> slotVos = ConvertUtil.convertList(list,TaskTimeSlotVo.class);
            slotVos.forEach(s->{
                s.checkSlot();
            });

            Map<Integer, List<TaskTimeSlotVo>> listMap =  slotVos.stream().
                    collect(Collectors.groupingBy(TaskTimeSlotVo::getSlot));
            List<Integer> dataList = new ArrayList<>();
            for(int i=0;i<timeSlotList.length;i++){

                Integer timeSlot = timeSlotList[i];
                List<TaskTimeSlotVo> s =  listMap.get(timeSlot);
                if(s!=null && !s.isEmpty()){
                    dataList.add(s.size());
                }else {
                    dataList.add(0);
                }
            }
            lists.add(dataList);

        });
        return new TaskDayLineVo(xData,lists);

    }

    @Override
    public TaskTimeOutLineVo getTimeOutLine() {

        AdminUserDO userDO = userMapper.selectById(getLoginUserId());


        Long assignee = getLoginUserId();
        Long deptId    =   userDO.getDeptId();
        Date startTime = DateUtil.offsetDay(new Date(), -8);
        Date endTime   = DateUtil.beginOfDay(new Date());
        List<String> xData =   systemDateMapper.getList(startTime,endTime);

        List<TaskStatisticsVo> myTimeOutTaskList = this.actRuActTimeMapper.getMyTaskTimeOut(assignee, startTime, endTime);

        List<Integer> myList = myTimeOutTaskList.stream().map(TaskStatisticsVo::getTotalCount).collect(Collectors.toList());

        List<TaskStatisticsVo> myDeptOutTaskList = this.actRuActTimeMapper.getMyDeptTaskTimeOut(deptId, startTime, endTime);

        List<Integer> deptList = myDeptOutTaskList.stream().map(TaskStatisticsVo::getTotalCount).collect(Collectors.toList());


        return new TaskTimeOutLineVo(xData,myList,deptList);
    }


}
